"""
数据库管理抽象接口
================

定义数据库管理器的抽象基类，所有具体的数据库实现都应该继承此接口。
"""

from abc import ABC, abstractmethod
from typing import Any, Optional, Union, Dict, List, AsyncGenerator
from contextlib import asynccontextmanager


class AbstractDatabaseManager(ABC):
    """抽象数据库管理器"""
    
    @abstractmethod
    async def connect(self) -> bool:
        """
        连接数据库
        
        Returns:
            是否连接成功
        """
        pass
    
    @abstractmethod
    async def disconnect(self):
        """断开数据库连接"""
        pass
    
    @abstractmethod
    async def execute(self, query: str, params: Optional[Dict[str, Any]] = None) -> Any:
        """
        执行SQL语句
        
        Args:
            query: SQL语句
            params: 参数字典
            
        Returns:
            执行结果
        """
        pass
    
    @abstractmethod
    async def fetch_one(self, query: str, params: Optional[Dict[str, Any]] = None) -> Optional[Dict[str, Any]]:
        """
        获取单条记录
        
        Args:
            query: SQL语句
            params: 参数字典
            
        Returns:
            记录字典，不存在则返回None
        """
        pass
    
    @abstractmethod
    async def fetch_many(
        self, 
        query: str, 
        params: Optional[Dict[str, Any]] = None,
        limit: Optional[int] = None
    ) -> List[Dict[str, Any]]:
        """
        获取多条记录
        
        Args:
            query: SQL语句
            params: 参数字典
            limit: 限制数量
            
        Returns:
            记录列表
        """
        pass
    
    @abstractmethod
    async def fetch_all(self, query: str, params: Optional[Dict[str, Any]] = None) -> List[Dict[str, Any]]:
        """
        获取所有记录
        
        Args:
            query: SQL语句
            params: 参数字典
            
        Returns:
            记录列表
        """
        pass
    
    @abstractmethod
    @asynccontextmanager
    async def transaction(self):
        """
        事务上下文管理器
        
        Yields:
            事务对象
        """
        pass
    
    @abstractmethod
    async def health_check(self) -> Dict[str, Any]:
        """
        健康检查
        
        Returns:
            健康状态信息
        """
        pass
    
    @abstractmethod
    async def get_connection_info(self) -> Dict[str, Any]:
        """
        获取连接信息
        
        Returns:
            连接信息字典
        """
        pass


class AbstractDatabaseConfig(ABC):
    """抽象数据库配置"""
    
    @property
    @abstractmethod
    def host(self) -> str:
        """数据库主机"""
        pass
    
    @property
    @abstractmethod
    def port(self) -> int:
        """数据库端口"""
        pass
    
    @property
    @abstractmethod
    def database(self) -> str:
        """数据库名"""
        pass
    
    @property
    @abstractmethod
    def username(self) -> str:
        """用户名"""
        pass
    
    @property
    @abstractmethod
    def password(self) -> str:
        """密码"""
        pass
    
    @property
    @abstractmethod
    def connection_url(self) -> str:
        """连接URL"""
        pass
    
    @property
    @abstractmethod
    def pool_size(self) -> int:
        """连接池大小"""
        pass
    
    @property
    @abstractmethod
    def max_overflow(self) -> int:
        """最大溢出连接数"""
        pass
    
    @property
    @abstractmethod
    def pool_timeout(self) -> int:
        """连接池超时时间"""
        pass


class AbstractQueryBuilder(ABC):
    """抽象查询构建器"""
    
    @abstractmethod
    def select(self, *columns) -> 'AbstractQueryBuilder':
        """选择列"""
        pass
    
    @abstractmethod
    def from_table(self, table: str) -> 'AbstractQueryBuilder':
        """指定表"""
        pass
    
    @abstractmethod
    def where(self, condition: str, **params) -> 'AbstractQueryBuilder':
        """添加WHERE条件"""
        pass
    
    @abstractmethod
    def join(self, table: str, condition: str) -> 'AbstractQueryBuilder':
        """添加JOIN"""
        pass
    
    @abstractmethod
    def order_by(self, column: str, desc: bool = False) -> 'AbstractQueryBuilder':
        """添加排序"""
        pass
    
    @abstractmethod
    def limit(self, count: int) -> 'AbstractQueryBuilder':
        """限制数量"""
        pass
    
    @abstractmethod
    def offset(self, count: int) -> 'AbstractQueryBuilder':
        """偏移量"""
        pass
    
    @abstractmethod
    def build(self) -> tuple[str, Dict[str, Any]]:
        """构建查询"""
        pass
